package com.siao.component
{
	import com.siao.display.Align;
	import com.siao.display.LayoutElement;
	import com.siao.display.Range;
	
	import flash.display.DisplayObject;
	
	/**
	 * 堆栈组件，该组件将忽略子项目中对齐属性，统一使用contentAlign的内容整体对齐
	 * @author SiaoLeon
	 */
	public class Stack extends LayoutElement
	{
		// -------------------------------------------------------------------------------------------------------- 静态常量
		
		// -------------------------------------------------------------------------------------------------------- 静态变量
		
		// -------------------------------------------------------------------------------------------------------- 静态方法
		
		// -------------------------------------------------------------------------------------------------------- 静态函数
		
		// -------------------------------------------------------------------------------------------------------- 属性
		
		private var _spacing:Number = 0;
		
		/**
		 * 间距
		 * @return
		 */
		public function get spacing():Number
		{
			return this._spacing;
		}
		
		public function set spacing(value:Number):void
		{
			this._spacing = value;
			
			this.measure();
		}
		
		private var _orientation:uint;
		
		/**
		 * 排列方式
		 * @return
		 */
		public function get orientation():uint
		{
			return this._orientation;
		}
		
		public function set orientation(value:uint):void
		{
			this._orientation = (value > Orientation.BOTTOM_TOP) ? value & 1 : value;
			
			this.measure();
		}
		
		private var _contentAlignH:uint;
		
		/**
		 * 横向对齐方式
		 * @return
		 */
		public function get contentAlignH():uint
		{
			return this._contentAlignH;
		}
		
		public function set contentAlignH(value:uint):void
		{
			this._contentAlignH = value;
			
			this.measure();
		}
		
		private var _contentAlignV:uint;
		
		/**
		 * 纵向对齐方式
		 * @return
		 */
		public function get contentAlignV():uint
		{
			return this._contentAlignV;
		}
		
		public function set contentAlignV(value:uint):void
		{
			this._contentAlignV = value;
			
			this.measure();
		}
		
		private var _itemWidth:Number;
		
		/**
		 * 项目宽度
		 * @return
		 */
		public function get itemWidth():Number
		{
			return this._itemWidth;
		}
		
		public function set itemWidth(value:Number):void
		{
			this._itemWidth = value;
		}
		
		private var _itemHeight:Number;
		
		/**
		 * 项目高度
		 * @return
		 */
		public function get itemHeight():Number
		{
			return this._itemHeight;
		}
		
		public function set itemHeight(value:Number):void
		{
			this._itemHeight = value;
		}
		
		private var _contentRange:Range = new Range();
		
		/**
		 * 内容实际范围
		 * @return
		 */
		public function get contentRange():Range
		{
			return this._contentRange;
		}
		
		/**
		 * 内容宽度
		 * @return
		 */
		public function get contentWidth():Number
		{
			return this._contentRange.width;
		}
		
		/**
		 * 内容高度
		 * @return
		 */
		public function get contentHeight():Number
		{
			return this._contentRange.height;
		}
		
		// -------------------------------------------------------------------------------------------------------- 变量
		
		// -------------------------------------------------------------------------------------------------------- 构造
		
		/**
		 * 构造函数
		 * @param orientation 排列方向
		 */
		public function Stack(orientation:uint=Orientation.LEFT_RIGHT)
		{
			super();
			
			this._orientation = (orientation > Orientation.RIGHT_LEFT) ? orientation & 1 : orientation;
		}
		
		// -------------------------------------------------------------------------------------------------------- 方法
		
		override public function resize():void
		{
			super.resize();
			
			this.measure();
		}
		
		override public function addChild(child:DisplayObject):DisplayObject
		{
			var result:DisplayObject = super.addChild(child);
			
			this.measure();
			
			return result;
		}
		
		override public function addChildAt(child:DisplayObject, index:int):DisplayObject
		{
			var result:DisplayObject = super.addChildAt(child, (index > super.numChildren) ? super.numChildren : index);
			
			this.measure();
			
			return result;
		}
		
		override public function removeChild(child:DisplayObject):DisplayObject
		{
			var result:DisplayObject = super.removeChild(child);
			
			this.measure();
			
			return result;
		}
		
		override public function removeChildAt(index:int):DisplayObject
		{
			var result:DisplayObject = super.removeChildAt(index);
			
			this.measure();
			
			return result;
		}
		
		//		override public function removeChildren(beginIndex:int=0, endIndex:int=2147483647):void
		//		{
		//			super.removeChildren(beginIndex, endIndex);
		//			
		//			this.measure();
		//		}
		
		/**
		 * 测量内容尺寸
		 */
		public function measure():void
		{
			this._contentRange = new Range();
			
			var noWidths:Array = new Array();
			var noHeights:Array = new Array();
			
			//遍历子项目，测量高宽
			for (var i:int = 0; i < this.numChildren; i++)
			{
				var item:DisplayObject = this.getChildAt(i);
				
				var marginLeft:Number = (item is LayoutElement) ? (item as LayoutElement).marginLeft : 0;
				var marginRight:Number = (item is LayoutElement) ? (item as LayoutElement).marginRight : 0;
				var marginTop:Number = (item is LayoutElement) ? (item as LayoutElement).marginTop : 0;
				var marginBottom:Number = (item is LayoutElement) ? (item as LayoutElement).marginBottom : 0;
				
				var itemWidth:Number = marginLeft + item.width + marginRight;
				var itemHeight:Number = marginTop + item.height + marginBottom;
				
				if (item is LayoutElement && item.width == 0)
				{
					noWidths.push(item);
				}
				
				if (item is LayoutElement && item.height == 0)
				{
					noHeights.push(item);
				}
				
				switch (this.orientation)
				{
					case Orientation.HORIZONTAL:
					case Orientation.LEFT_RIGHT:
					case Orientation.RIGHT_LEFT:
						this.contentRange.width = (i == 0) ? itemWidth : this.contentWidth + this.spacing + itemWidth;
						this.contentRange.height = (i == 0) ? itemHeight : Math.max(this.contentHeight, itemHeight);
						break;
					
					case Orientation.VERTICAL:
					case Orientation.TOP_BOTTOM:
					case Orientation.BOTTOM_TOP:
						this.contentRange.width = (i == 0) ? itemWidth : Math.max(this.contentWidth, itemWidth);
						this.contentRange.height = (i == 0) ? itemHeight : this.contentHeight + this.spacing + itemHeight;
						break;
				}
			}
			
			//将未设置宽度的布局项目填充最大宽度数值
			for each (var noWidth:LayoutElement in noWidths)
			{
				switch (this.orientation)
				{
					case Orientation.HORIZONTAL:
					case Orientation.LEFT_RIGHT:
					case Orientation.RIGHT_LEFT:
						noWidth.maxWidth = (this.width - this.paddingLeft - this.paddingRight - this.contentWidth) / noWidths.length;
						break;
					
					case Orientation.VERTICAL:
					case Orientation.TOP_BOTTOM:
					case Orientation.BOTTOM_TOP:
						noWidth.maxWidth = this.contentRange.width;
						break;
				}
			}
			
			//将未设置高度的布局项目填充最大高度数值
			for each (var noHeight:LayoutElement in noHeights)
			{
				switch (this.orientation)
				{
					case Orientation.HORIZONTAL:
					case Orientation.LEFT_RIGHT:
					case Orientation.RIGHT_LEFT:
						noHeight.maxHeight = this.contentRange.height;
						break;
					
					case Orientation.VERTICAL:
					case Orientation.TOP_BOTTOM:
					case Orientation.BOTTOM_TOP:
						noHeight.maxHeight = (this.height - this.paddingTop - this.paddingBottom - this.contentHeight) / noHeights.length;
						break;
				}
			}
			
			//如果有未设定高宽的布局项目，则重置内容高宽为最大值
			if (noWidths.length > 0)
			{
				this.contentRange.width = this.width - this.paddingLeft - this.paddingRight;
			}
			
			if (noHeights.length > 0)
			{
				this.contentRange.height = this.height - this.paddingTop - this.paddingBottom;
			}
			
			this.contentRange.left = (this.contentAlignH == Align.LEFT) ? this.paddingLeft : (this.contentAlignH == Align.RIGHT) ? this.width - this.contentWidth - this.paddingRight : (this.width - this.contentWidth) / 2;
			this.contentRange.right = this.width - this.contentRange.left - this.contentRange.width;
			this.contentRange.top = (this.contentAlignV == Align.TOP) ? this.paddingTop : (this.contentAlignV == Align.BOTTOM) ? this.height - this.contentHeight - this.paddingBottom : (this.height - this.contentHeight) / 2;
			this.contentRange.bottom = this.height - this.contentRange.top - this.contentRange.height;
			
			this.arrange();
		}
		
		/**
		 * 排列子项目
		 */
		public function arrange():void
		{
			for (var i:int = 0; i < this.numChildren; i++)
			{
				var item:DisplayObject = this.getChildAt(i);
				
				var marginLeft:Number = (item is LayoutElement) ? (item as LayoutElement).marginLeft : 0;
				var marginRight:Number = (item is LayoutElement) ? (item as LayoutElement).marginRight : 0;
				var marginTop:Number = (item is LayoutElement) ? (item as LayoutElement).marginTop : 0;
				var marginBottom:Number = (item is LayoutElement) ? (item as LayoutElement).marginBottom : 0;
				
				var iWidth:Number = (isNaN(this._itemWidth)) ? marginLeft + item.width + marginRight : this.itemWidth;
				var iHeight:Number = (isNaN(this.itemHeight)) ? marginTop + item.height + marginBottom : this.itemHeight;
				
				//忽略子项目对齐方式
				if (item is LayoutElement && (item as LayoutElement).alignH != Align.NONE)
				{
					(item as LayoutElement).alignH = Align.NONE;
				}
				
				if (item is LayoutElement && (item as LayoutElement).alignV != Align.NONE)
				{
					(item as LayoutElement).alignV = Align.NONE;
				}
				
				//根据排列方式定位子项目坐标
				switch (this.orientation)
				{
					case Orientation.HORIZONTAL:
					case Orientation.LEFT_RIGHT:
						item.x = (i == 0) ? this.contentRange.left + marginLeft : this.contentRange.left + this.contentWidth + this.spacing + marginLeft;
						item.y = (this.contentAlignV == Align.TOP) ? this.contentRange.top + marginTop : (this.contentAlignV == Align.BOTTOM) ? this.contentRange.top + marginTop + this.contentHeight - iHeight : this.contentRange.top + marginTop + (this.contentHeight - iHeight) / 2;
						this.contentRange.width = (i == 0) ? iWidth : this.contentWidth + this.spacing + iWidth;
						break;
					
					case Orientation.RIGHT_LEFT:
						item.x = (i == 0) ? this.contentRange.left + this.contentWidth - iWidth + marginLeft : this.contentRange.left - this.spacing - iWidth + marginLeft;
						item.y = (this.contentAlignV == Align.TOP) ? this.contentRange.top + marginTop : (this.contentAlignV == Align.BOTTOM) ? this.contentRange.top + marginTop + this.contentHeight - iHeight : this.contentRange.top + marginTop + (this.contentHeight - iHeight) / 2;
						this.contentRange.width = (i == 0) ? iWidth : this.contentWidth + this.spacing + iWidth;
						break;
					
					case Orientation.VERTICAL:
					case Orientation.TOP_BOTTOM:
						item.x = (this.contentAlignH == Align.LEFT) ? this.contentRange.left + marginLeft : (this.contentAlignH == Align.RIGHT) ? this.contentRange.left + marginLeft + this.contentWidth - iWidth : this.contentRange.left + marginLeft + (this.contentWidth - iWidth) / 2;
						item.y = (i == 0) ? this.contentRange.top + marginTop : this.contentRange.top + this.contentHeight + this.spacing + marginTop;
						this.contentRange.height = (i == 0) ? iHeight : this.contentHeight + this.spacing + iHeight;
						break;
					
					case Orientation.BOTTOM_TOP:
						item.x = (this.contentAlignH == Align.LEFT) ? this.contentRange.left + marginLeft : (this.contentAlignH == Align.RIGHT) ? this.contentRange.left + marginLeft + this.contentWidth - iWidth : this.contentRange.left + marginLeft + (this.contentWidth - iWidth) / 2;
						item.y = (i == 0) ? this.contentRange.top + this.contentHeight - iHeight + marginTop : this.contentRange.top + this.contentHeight - this.spacing - iHeight + marginTop;
						this.contentRange.height = (i == 0) ? iHeight : this.contentHeight + this.spacing + iHeight;
						break;
				}
			}
		}
	
		// -------------------------------------------------------------------------------------------------------- 函数
	
	}
}

